/*
 * Copyright 2013 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package io.netty.example.http.helloworld;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.DecoderResult;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.InterfaceHttpData.HttpDataType;
import static io.netty.handler.codec.http.HttpHeaders.Names.*;
import static io.netty.handler.codec.http.HttpHeaders.*;
import static io.netty.handler.codec.http.HttpResponseStatus.*;
import static io.netty.handler.codec.http.HttpVersion.*;

public class HttpHelloWorldServerHandler extends ChannelInboundHandlerAdapter {
    private static final byte[] CONTENT = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' };

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }
    
	private Command parse(HttpRequest req) throws Exception{
		Command cmd = new Command();
		String uri = req.getUri();
		int idx = uri.indexOf('?');
		String pre = uri.substring(1);
		String suffix = null;
		if(idx > 0){
			pre = uri.substring(1, idx);
			suffix = uri.substring(idx + 1);
		}
		String[] ary = pre.split("/");
		if(ary.length == 5){
			cmd.clientType = ary[0];
			cmd.planeId = Long.parseLong(ary[1]);
			cmd.bundleId = Long.parseLong(ary[2]);
			cmd.versionId = Long.parseLong(ary[3]);
			idx = ary[4].lastIndexOf('.');
			if(idx > 0){
				cmd.beanName = ary[4].substring(0, idx);
				cmd.methodName = ary[4].substring(idx+1);
			}
		}
		if(suffix != null && suffix.length() > 0){
			cmd.params = new LinkedHashMap<String, Object>();
			ary = suffix.split("&");
			for(int i = 0; i < ary.length; i++){
				if(ary[i] == null || ary[i].trim().isEmpty())
					continue;
				String[] items = ary[i].split("=");
				if(items.length != 2)
					continue;
				String key = items[0];
				if(key == null)
					continue;
				key = key.trim();
				if(key.isEmpty())
					continue;
				String val = items[1];
				if(val == null)
					continue;
				val = val.trim();
				cmd.params.put(key, val);
			}
		}
		if(cmd.valid()){
			List<String> cookies = req.headers().getAll(COOKIE);
			if(cookies != null){
				for(int i = 0; i < cookies.size(); i++){
					System.out.print(cookies.get(i));
				}
			}
		}
        if(req.getMethod() == HttpMethod.POST){
        	HttpPostRequestDecoder postDecoder = new HttpPostRequestDecoder(req);
        	InterfaceHttpData data = postDecoder.getBodyHttpData("params");
        	if(data != null && data.getHttpDataType() == HttpDataType.Attribute){
        		Attribute attr = (Attribute) data;
        		String params = attr.getValue();
        		System.out.println(params);
        	}
        }
		
		return cmd;
	}

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
            HttpRequest req = (HttpRequest) msg;
            
            System.out.println(req.getUri());
            Command cmd = parse(req);
//           DecoderResult dr = req.getDecoderResult();
//           DefaultFullHttpRequest dfr = null;
           

            if (is100ContinueExpected(req)) {
                ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
            }
            boolean keepAlive = isKeepAlive(req);
            FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(CONTENT));
            response.headers().set(CONTENT_TYPE, "text/plain");
            response.headers().set(CONTENT_LENGTH, response.content().readableBytes());

            if (!keepAlive) {
                ctx.write(response).addListener(ChannelFutureListener.CLOSE);
            } else {
                response.headers().set(CONNECTION, Values.KEEP_ALIVE);
                ctx.write(response);
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}
